<template>
	<div class="container">
		<h2 style="text-align: center;">{{ id ? '修改' : '创建' }}零星用工申请</h2>
		<a-form ref="formRef" :model="formState" layout="vertical" @finish="savePurchase">
			<a-row :gutter="20">
				<a-col :span="6">
					<a-form-item label="选择项目" name="project_id" :rules="{ required: true, message: '请选择项目' }">
						<a-select v-model:value="formState.project_id" :show-search="true" placeholder="请选择项目" :options="projectOptions" option-filter-prop="label" @change="changeProject"></a-select>
					</a-form-item>
				</a-col>
				<a-col :span="6">
					<a-form-item label="送达地址" name="deliver_address" :rules="{ required: true, message: '请输入送达地址' }">
						<a-input v-model:value="formState.deliver_address" readonly="readonly" placeholder="请输入送达地址" disabled />
					</a-form-item>
				</a-col>
				<a-col :span="6">
					<a-form-item label="接收联系人" name="receiver_id" :rules="{ required: true, message: '请选择接收联系人' }">
						<a-select v-model:value="formState.receiver_id" :show-search="true" placeholder="请选择接收联系人" :options="userlist" option-filter-prop="label" @change="changeUser"></a-select>
					</a-form-item>
				</a-col>
				<a-col :span="6">
					<a-form-item label="联系人手机" name="receiver_tel" :rules="{ required: true, message: '请输入联系人电话' }">
						<a-input v-model:value="formState.receiver_tel" placeholder="请输入联系人电话" readonly="readonly" disabled />
					</a-form-item>
				</a-col>
				<a-col :span="6">
					<a-form-item label="需求时间" name="deliver_time" :rules="{ required: true, message: '请输入送达日期' }">
						<a-date-picker v-model:value="formState.deliver_time" value-format="YYYY-MM-DD HH:mm:ss" show-time style="width:100%" />
					</a-form-item>
				</a-col>
				<a-col :span="6">
					<a-form-item label="施工阶段" name="build_phase" :rules="{ required: true, message: '请选择施工阶段' }">
						<a-select v-model:value="formState.build_phase" style="width: 100%" placeholder="请选择施工阶段" :options="buildPhaseList" option-filter-prop="label"></a-select>
					</a-form-item>
				</a-col>
				<a-col :span="6">
					<a-form-item label="劳务单位" name="supplier_id" :rules="{ required: true, message: '请选择劳务单位' }">
						<a-select v-model:value="formState.supplier_id" style="width: 100%" placeholder="请选择劳务单位" :options="supplierList" option-filter-prop="label" @change="changeSupplier"></a-select>
					</a-form-item>
				</a-col>
				<a-col :span="6">
					<a-form-item label="合同" name="contract_id" :rules="{ required: true, message: '请选择合同' }">
						<a-select v-model:value="formState.contract_id" style="width: 100%" placeholder="请选择合同" :options="innerContractList" option-filter-prop="label"></a-select>
					</a-form-item>
				</a-col>
				<a-col :span="6">
					<a-form-item label="是否其他单位完成" name="other_supplier_id" :rules="{ required: false, message: '请选择其他完成单位' }">
						<a-select v-model:value="formState.other_supplier_id" style="width: 100%" placeholder="请选择其他完成单位" :options="otherSupplierList" option-filter-prop="label"></a-select>
					</a-form-item>
				</a-col>
				<a-col :span="18">
					<a-form-item label="需求内容" name="remark" :rules="{ required: true, message: '请输入需求内容' }">
						<a-input v-model:value="formState.remark" style="width:100%" placeholder="请输入需求内容" />
					</a-form-item>
				</a-col>
				<a-col :span="24">
					<a-form-item label="主要工作内容及要求" name="detail_remark" :rules="{ required: true, message: '请输入主要工作内容及要求' }">
						<a-textarea v-model:value="formState.detail_remark" style="width:100%" placeholder="请输入主要工作内容及要求" />
					</a-form-item>
				</a-col>


				<a-col :span="24">
					<h4>本次申请物资清单</h4>
					<div class="table-toolbar mb-3">
						<a-space>
							<a-button type="primary" @click="addMaterialModel">
								<plus-outlined />新增
							</a-button>
							<a-button class="cache-btn" @click="handleCache">
								<DeliveredProcedureOutlined />暂存
							</a-button>
						</a-space>
					</div>

					<a-table :data-source="formState.materials" :columns="planMaterialColumns" :row-key="(record) => record.key" :pagination="false">
						<template #bodyCell="{ column, record, index }">
							<template v-if="column.dataIndex === 'id'">{{ index + 1 }}</template>
							<template v-if="column.dataIndex === 'name'">
								<a-form-item :name="['materials', index, 'source_id']" :rules="{ required: true, message: '请选择材料名称' }">
									<a-tree-select v-model:value="formState.materials[index].source_id" :show-search="true" placeholder="请选择材料名称" allow-clear tree-default-expand-all :tree-data="materialOptions" tree-node-filter-prop="label" style="width:100%" @change="(id) => handleSourceChange(id, record)">
										<template #title="{ label }">{{ label }}</template>
									</a-tree-select>
								</a-form-item>
							</template>
							<template v-else-if="column.dataIndex === 'model'">
								<a-form-item :name="['materials', index, 'model']" :rules="{ required: true, message: '请选择规格' }">
									<a-select v-model:value="formState.materials[index].model" :show-search="true" placeholder="请选择" :options="modelOptions[record.source_id]" allow-clear :field-names="{ value: 'model', label: 'modelName' }" style="width:100%" @change="(model) => handleModelChange(record, model)"></a-select>
								</a-form-item>
							</template>
							<template v-else-if="column.dataIndex === 'unit'">
								<a-form-item :name="['materials', index, 'unit']" :rules="{ required: true, message: '请选择计量单位' }">
									<a-select v-model:value="formState.materials[index].unit" :show-search="true" placeholder="请选择" :options="unitOptions[`${record.source_id}_${record.model}`] || []" :field-names="{ value: 'unit', label: 'unit' }" style="width:100%" @change="(unit) => changeUnit(record, unit, unitOptions[`${record.source_id}_${record.model}`])"></a-select>
								</a-form-item>
							</template>
							<template v-else-if="column.dataIndex === 'quantity'">
								<a-form-item :name="['materials', index, 'quantity']" :rules="{ required: true, message: '请输入数量' }">
									<a-input-number v-model:value="formState.materials[index].quantity" placeholder="请输入数量" @blur="checkqty(record)" />
								</a-form-item>
							</template>
							<template v-else-if="column.dataIndex === 'memo'">
								<a-form-item :name="['materials', index, 'memo']">
									<a-input v-model:value="formState.materials[index].memo" placeholder="请输入备注" />
								</a-form-item>
							</template>
							<template v-else-if="column.key === 'operation'">
								<a-space>
									<a-popconfirm title="确定要删除当前材料吗？" ok-text="是" cancel-text="否" @confirm="deleteMaterialModel(record.key)">
										<a-button type="link" style="color:#ff7875">
											<delete-outlined />删除
										</a-button>
									</a-popconfirm>
								</a-space>
							</template>
						</template>
					</a-table>
				</a-col>
				<a-col :span="24" style="margin-top: 24px;">
					<a-form-item label="备注" name="memo">
						<a-textarea v-model:value="formState.memo" :auto-size="{ minRows: 4, maxRows: 6 }"></a-textarea>
					</a-form-item>
				</a-col>
			</a-row>

			<a-row :gutter="20">
				<a-col :span="24" class="py-4 text-center">
					<a-space>
						<a-button class="cache-btn" @click="handleCache">
							<DeliveredProcedureOutlined />暂存
						</a-button>
						<a-button v-if="!formState.id || ![0,1,2].includes(formState.workflow_status)" type="primary" html-type="submit">
							<save-outlined />保存
						</a-button>

						<a-workflow v-if="formState.id" v-model:status="formState.workflow_status" module="aFewEmploy" :target-id="formState.id" :project-id="formState.project_id" :code="formState.code" :user-id="formState.apply_id" @submit="submitPurchase"></a-workflow>

						<a-button @click="closeTab('/aFewEmploy')">
							<close-outlined />关闭
						</a-button>
					</a-space>
				</a-col>
			</a-row>
		</a-form>
	</div>
</template>

<script setup>
import { ref, computed, onMounted, getCurrentInstance, inject } from "vue";
import { post, listToTree, postJson } from "../utils";
import { useRoute } from "vue-router";
import { add, subtract } from "@/utils/operation.js";
//缓存数据
const handleCache = () => {
	localStorage.setItem("aFewEmploy-save", JSON.stringify(formState.value));
	proxy.$message.success("缓存成功");
};
const route = useRoute();
const id = computed(() => {
	return route.params.id || 0;
});
const formState = ref({ materials: [] });
const contractlist = ref([]); //	合同列表
const userlist = ref([]); // 联系人列表
const buildPhaseList = ref([]); // 施工阶段
const otherSupplierList = ref([]); // 其他完成单位
const supplierList = ref([]); // 合同供应商
const formRef = ref();
const { proxy } = getCurrentInstance();
const addMaterialModel = () => {
	if (!formState.value.contract_id || !formState.value.supplier_id) {
		proxy.$message.warning("请先确定劳务单位和合同");
		return;
	}
	formState.value.materials.push({ key: formState.value.materials.length });
};

const planMaterialColumns = [
	{
		title: "ID",
		dataIndex: "id",
		width: 60,
		align: "center"
	},
	{
		title: "物资名称",
		dataIndex: "name",
		width: 200,
		ellipsis: true
	},
	{
		title: "型号规格",
		dataIndex: "model",
		width: 150,
		ellipsis: true
	},
	{
		title: "单位",
		dataIndex: "unit",
		width: 130,
		align: "center"
	},
	{
		title: "预约数量",
		dataIndex: "quantity",
		width: 100,
		align: "center"
	},
	{
		title: "合同剩余量",
		dataIndex: "pendingQuantity",
		width: 100,
		align: "center"
	},
	{
		title: "备注",
		dataIndex: "memo",
		width: 200,
		align: "center"
	},
	{
		title: "操作",
		key: "operation",
		sorter: false,
		fixed: "right",
		width: 160,
		align: "center"
	}
];

post("dictionary", { root_id: 1288 }).then(data => {
	buildPhaseList.value = data;
});
//projectOptions
const projectOptions = ref([]);

const handleSourceChange = (id, record) => {
	record.id = null;
	record.model = null;
	record.unit = null;
	if (!id) return;
	post("material", { source_id: id, page_size: Infinity, attributes: 'id,attr,model,source_id,unit', status: 1 }).then(({ data }) => {
		modelOptions.value[id] = data.map(d => {
			if (d.attr) d.model = `${d.model}（${d.attr}）`;
			return d;
		});
	});
};

const handleModelChange = (record, model) => {
	unitOptions.value[record.source_id] = [];
	record.id = null;
	record.unit = null;
	if (!unitOptions.value[`${record.source_id}_${record.model}`]) {
		post("material", { source_id: record.source_id, page_size: Infinity, status: 1 }).then(({ data }) => {
			const selectList = [];
			for (const d of data) {
				if (d.model !== model) {
					continue;
				}
				selectList.push(d);
			}
			unitOptions.value[`${record.source_id}_${record.model}`] = selectList;
		});
	}
};
const changeUnit = async (record, unit, unitOpt) => {
	const material = unitOpt.filter(item => item.unit === unit)[0];
	record.id = material.id;
	if (record.id) {
		const materialIds = formState.value.materials.filter(item => item.id === record.id);
		if (materialIds.length > 1) {
			proxy.$message.error("请勿选择相同的物料");
			record.id = null;
			record.unit = null;
		}

		const contractMaterialInfos2MaterialId = contractlist.value.reduce((target, item) => {
			if (item.id !== formState.value.contract_id) return target;
			for (const material of item.materials) {
				if (!target[material.id]) {
					target[material.id] = 0;
				}
				target[material.id] = add([target[material.id], material.ContractMaterial?.pending_quantity || 0]);
			}
			return target;
		}, {});
		record.pendingQuantity = contractMaterialInfos2MaterialId[record.id];
	}
};

const materialInfo = ref({});
const materialOptions = ref([]);
const modelOptions = ref({});
const unitOptions = ref({});
const changeProject = project_id => {
	return new Promise((resolve, reject) => {
		formState.value.receiver_id = null;
		Promise.all([
			getUserOptions(project_id),
			getContractOtherSuppliers(project_id),
			getContractSuppliers(project_id),
			getMaterialOptions(project_id),
		]).then(() => {
			resolve()
		}).catch(e => reject(e));
	});
};
const getUserOptions = async project_id => {
	return new Promise((resolve) => {
		post("project/user", { project_id, scene: "main", status: "1" }).then(data => {
			userlist.value = data.map(d => ({
				label: d.fullname || d.username,
				value: d.id,
				mobile: d.mobile
			}));
			resolve();
		});
	})
};
const getContractOtherSuppliers = project_id => {
	return new Promise((resolve) => {
		post("contract/projectSuppliers", { project_id: project_id }).then(data => {
			otherSupplierList.value = data.map(d => ({
				label: d.company_name,
				value: d.id,
			}));
			resolve();
		});
	})
}
const getContractSuppliers = project_id => {
	return new Promise((resolve) => {
		post("contract/projectSuppliers", { project_id: project_id, contract_type: "5" }).then(data => {
			supplierList.value = data.map(d => ({
				label: d.company_name,
				value: d.id,
			}));
			resolve();
		});
	})
}
const getMaterialOptions = (project_id) => {
	return new Promise((resolve) => {
		postJson("contract/apply", { project_id: project_id, types: [5] }).then(data => {
			materialInfo.value = {};
			materialOptions.value = [];
			modelOptions.value = {};
			unitOptions.value = {};

			if (!data.length) {
				contractlist.value = [];
				formState.value.project_id = null;
				proxy.$message.error("当前项目尚未绑定合同");
			}

			contractlist.value = data;
			const materials = data
				.map(item => item.materials)
				.reduce((res, curr) => {
					res.push(...curr);
					return res;
				}, []);
			materialInfo.value = materials.reduce((res, curr) => {
				//过滤混凝土
				if (curr.source_id === 3 || curr.parent_id === 3) return res;

				if (!res[curr.id]) {
					const model = curr.attr ? `${curr.model}（${curr.attr}）` : curr.model;
					res[curr.id] = {
						name: curr.name,
						model: model, // 型号
						unit: curr.ContractMaterial.unit, // 单位 物资中的单位有问题，显示为id
						source_id: curr.source_id, // 字典物料id
						quantity: 0 // 当前物资数量
					};
				}
				// 物资数量汇总
				const quantity = Number(curr.ContractMaterial.quantity);
				res[curr.id].quantity += isNaN(quantity) ? 0 : quantity;
				return res;
			}, {});
			materialOptions.value = Object.keys(materialInfo.value)
				.map(materialId => {
					return {
						value: materialInfo.value[materialId].source_id,
						label: materialInfo.value[materialId].name
					};
				})
				.reduce((res, curr) => {
					const ids = res.map(item => item.value);
					if (!ids.includes(curr.value)) {
						res.push(curr);
					}
					return res;
				}, []);
			const sourceIds = materialOptions.value.map(item => item.value);
			modelOptions.value = sourceIds.reduce((res, sourceId) => {
				const materialIds = Object.keys(materialInfo.value).filter(materialId => materialInfo.value[materialId].source_id === sourceId);
				res[sourceId] = materialIds.map(materialId => {
					return {
						id: Number(materialId),
						model: materialInfo.value[materialId].model
					};
				});
				return res;
			}, {});

			unitOptions.value = Object.keys(materialInfo.value).reduce((res, materialId) => {
				res[materialId] = [
					{
						name: materialInfo.value[materialId].unit,
						label: materialInfo.value[materialId].unit
					}
				];
				return res;
			}, {});
			//自动完善地址信息
			const projectInfo = projectOptions.value.find(d => d.value === project_id);
			formState.value.deliver_address = projectInfo?.address;
			resolve()
		});
	})
}
const changeUser = (userId) => {
	const user = userlist.value.find(d => d.value === userId);
	formState.value.receiver = user.label;
	formState.value.receiver_tel = user.mobile;
}

const changeSupplier = () => {
	formState.value.contract_id = null;
}
const innerContractList = computed(() => {
	if (!formState.value.supplier_id) return [];
	return contractlist.value.filter((item) => {
		return item.supplier_id === formState.value.supplier_id;
	}).map(item => {
		return {
			label: item.name,
			value: item.id
		}
	})
})
//检验数量
const checkqty = async record => {
	if (record.id > 0) {
		if (record.quantity > record.pendingQuantity) {
			proxy.$message.error("预约清单数量不能超过合同剩余量");
			record.quantity = record.pendingQuantity;
		}
		if (parseFloat(record.quantity) === 0) {
			record.quantity = null;
		}
	}
};
onMounted(async () => {
	const cacheData = localStorage.getItem("aFewEmploy-save");
	formState.value = JSON.parse(cacheData) || formState.value;
	const projectList = await post("department/projects?type=3")
	projectOptions.value = projectList.data.map(d => {
		return {
			value: d.id,
			label: d.name,
			leader: d.leader,
			phone: d.phone,
			address: d.address
		};
	});
	if (id.value) {
		post("aFewEmploy/info", { id: id.value }).then(async data => {
			await changeProject(data.project.id);
			const contractMaterialInfos2MaterialId = contractlist.value.reduce((target, item) => {
				if (item.id !== data.contract_id) return target;
				for (const material of item.materials) {
					if (!target[material.id]) {
						target[material.id] = 0;
					}
					target[material.id] = add([target[material.id], material.ContractMaterial?.pending_quantity || 0]);
				}
				return target;
			}, {});
			data.materials = data.materials.map(item => {
				const { quantity, unit, memo } = item.AFewEmployMaterial;
				const pendingQuantity = contractMaterialInfos2MaterialId[item.id];
				return {
					...item,
					quantity,
					unit,
					memo,
					pendingQuantity,
				};
			});
			formState.value = data;
		})
	} else if (formState.value?.project_id) {
		Promise.all([
			getUserOptions(formState.value?.project_id),
			getContractSuppliers(formState.value?.project_id),
			getMaterialOptions(formState.value?.project_id)
		])
	}
});

const savePurchase = () => {
	formRef.value
		.validate()
		.then(() => {
			proxy.$message.destroy();
			const params = { ...formState.value };

			if (!contractlist.value.length) {
				proxy.$message.error("当前项目尚未绑定合同");
				return;
			}

			if (!params.materials.length) {
				proxy.$message.error("请添加材料清单");
				return;
			}

			params.materials = JSON.stringify(
				params.materials.map(({ id, unit, quantity, memo }) => {
					return {
						id,
						unit,
						quantity,
						memo
					};
				})
			);

			post("aFewEmploy/save", params)
				.then(() => {
					if (id.value) {
						proxy.$message.success("零星用工申请修改成功", 1);
					} else {
						proxy.$message.success("零星用工申请创建成功", 1);
					}

					closeTab("/aFewEmploy");
					localStorage.removeItem("aFewEmploy-save");
				})
				.catch(err => {
					proxy.$message.error(err);
				});
		})
		.catch(err => {
			proxy.$message.error(err.message);
		});
};

const submitPurchase = () => {
	proxy.$message.success("物资提交成功", 1);
	closeTab("/aFewEmploy");
};

const materialModelOptions = ref({});
/**
 const copyMaterialModel = record => {
 formState.value.materials.push({ ...record, key: formState.value.materials.length });
 }; */

const deleteMaterialModel = key => {
	const { materials } = formState.value;

	const index = materials.findIndex(d => d.key === key);
	if (index === false) return;
	materials.splice(index, 1);

	formState.value = {
		...formState.value,
		materials: materials.map((d, i) => {
			d.key = i;
			return d;
		})
	};
};

//调用父页面closeTab方法
/*
//父页面定义closeTab方法
provide("closeTab", path => {

});
*/
const closeTab = inject("closeTab");
</script>

<style scoped lang="scss">
.container {
  background: #fff;
  padding: 12px;

  h2 {
    font-size: 16px;
    font-weight: 600;
    line-height: 30px;
    margin-bottom: 20px;
  }

  h3 {
    line-height: 40px;
    font-size: 16px;
    font-weight: 400;
    margin-bottom: 20px;

    display: flex;
    align-items: center;

    &:before {
      content: "";
      display: block;
      width: 2px;
      height: 20px;
      background: rgb(24, 144, 255);
      margin-right: 10px;
    }
  }

  h4 {
    font-weight: 600;
    margin: 15px 0;
    line-height: 30px;
  }
}

:deep(.ant-table-cell) .ant-form-item {
  margin-bottom: 0;

  .ant-form-item-explain {
    position: absolute;
    bottom: -24px;
  }
}

.cache-btn {
  background-color: #0d9424;
  color: #fff;
}
</style>
